//#include "stdafx.h"
#include "CalcSys_L32.h"

#define L32_MAP_SIZE				1556
const unsigned char L32_aMap[L32_MAP_SIZE] = {
	0x01,0x00,0x36,0x01,0x9A,0x00,0x00,0x00,0x00,0x00,0x47,0xDC,0xFF,0xFF,0x01,0x00,0x01,0x00,0x95,0xDE,
	0xFF,0xFF,0x02,0x00,0x02,0x00,0xE3,0xE0,0xFF,0xFF,0x03,0x00,0x03,0x00,0x31,0xE3,0xFF,0xFF,0x04,0x00,
	0x04,0x00,0x7F,0xE5,0xFF,0xFF,0x05,0x00,0x05,0x00,0xCD,0xE7,0xFF,0xFF,0x06,0x00,0x06,0x00,0x1B,0xEA,
	0xFF,0xFF,0x07,0x00,0x07,0x00,0x69,0xEC,0xFF,0xFF,0x08,0x00,0x08,0x00,0xB7,0xEE,0xFF,0xFF,0x09,0x00,
	0x09,0x00,0x05,0xF1,0xFF,0xFF,0x0A,0x00,0x0A,0x00,0x53,0xF3,0xFF,0xFF,0x0B,0x00,0x0B,0x00,0xA1,0xF5,
	0xFF,0xFF,0x0C,0x00,0x0C,0x00,0xEF,0xF7,0xFF,0xFF,0x0D,0x00,0x0D,0x00,0x3D,0xFA,0xFF,0xFF,0x0E,0x00,
	0x0E,0x00,0x8B,0xFC,0xFF,0xFF,0x0F,0x00,0x0F,0x00,0xD9,0xFE,0xFF,0xFF,0x10,0x00,0x10,0x00,0x27,0x01,
	0x00,0x00,0x11,0x00,0x11,0x00,0x75,0x03,0x00,0x00,0x12,0x00,0x12,0x00,0xC3,0x05,0x00,0x00,0x13,0x00,
	0x13,0x00,0x11,0x08,0x00,0x00,0x14,0x00,0x14,0x00,0x5F,0x0A,0x00,0x00,0x15,0x00,0x15,0x00,0xAD,0x0C,
	0x00,0x00,0x16,0x00,0x16,0x00,0xFB,0x0E,0x00,0x00,0x17,0x00,0x17,0x00,0x49,0x11,0x00,0x00,0x18,0x00,
	0x18,0x00,0x97,0x13,0x00,0x00,0x19,0x00,0x19,0x00,0xE5,0x15,0x00,0x00,0x1A,0x00,0x1A,0x00,0x33,0x18,
	0x00,0x00,0x1B,0x00,0x1B,0x00,0x81,0x1A,0x00,0x00,0x1C,0x00,0x1C,0x00,0xCF,0x1C,0x00,0x00,0x1D,0x00,
	0x1D,0x00,0x1D,0x1F,0x00,0x00,0x1E,0x00,0x1E,0x00,0x6B,0x21,0x00,0x00,0x1F,0x00,0x1F,0x00,0xB9,0x23,
	0x00,0x00,0x01,0x00,0x00,0x00,0x6E,0xDD,0xFF,0xFF,0x02,0x00,0x01,0x00,0xBC,0xDF,0xFF,0xFF,0x03,0x00,
	0x02,0x00,0x0A,0xE2,0xFF,0xFF,0x04,0x00,0x03,0x00,0x58,0xE4,0xFF,0xFF,0x05,0x00,0x04,0x00,0xA6,0xE6,
	0xFF,0xFF,0x06,0x00,0x05,0x00,0xF4,0xE8,0xFF,0xFF,0x07,0x00,0x06,0x00,0x42,0xEB,0xFF,0xFF,0x08,0x00,
	0x07,0x00,0x90,0xED,0xFF,0xFF,0x09,0x00,0x08,0x00,0xDE,0xEF,0xFF,0xFF,0x0A,0x00,0x09,0x00,0x2C,0xF2,
	0xFF,0xFF,0x0B,0x00,0x0A,0x00,0x7A,0xF4,0xFF,0xFF,0x0C,0x00,0x0B,0x00,0xC8,0xF6,0xFF,0xFF,0x0D,0x00,
	0x0C,0x00,0x16,0xF9,0xFF,0xFF,0x0E,0x00,0x0D,0x00,0x64,0xFB,0xFF,0xFF,0x0F,0x00,0x0E,0x00,0xB2,0xFD,
	0xFF,0xFF,0x10,0x00,0x0F,0x00,0x00,0x00,0x00,0x00,0x11,0x00,0x10,0x00,0x4E,0x02,0x00,0x00,0x12,0x00,
	0x11,0x00,0x9C,0x04,0x00,0x00,0x13,0x00,0x12,0x00,0xEA,0x06,0x00,0x00,0x14,0x00,0x13,0x00,0x38,0x09,
	0x00,0x00,0x15,0x00,0x14,0x00,0x86,0x0B,0x00,0x00,0x16,0x00,0x15,0x00,0xD4,0x0D,0x00,0x00,0x17,0x00,
	0x16,0x00,0x22,0x10,0x00,0x00,0x18,0x00,0x17,0x00,0x70,0x12,0x00,0x00,0x19,0x00,0x18,0x00,0xBE,0x14,
	0x00,0x00,0x1A,0x00,0x19,0x00,0x0C,0x17,0x00,0x00,0x1B,0x00,0x1A,0x00,0x5A,0x19,0x00,0x00,0x1C,0x00,
	0x1B,0x00,0xA8,0x1B,0x00,0x00,0x1D,0x00,0x1C,0x00,0xF6,0x1D,0x00,0x00,0x1E,0x00,0x1D,0x00,0x44,0x20,
	0x00,0x00,0x1F,0x00,0x1E,0x00,0x92,0x22,0x00,0x00,0x00,0x00,0x01,0x00,0x6E,0xDD,0xFF,0xFF,0x01,0x00,
	0x02,0x00,0xBC,0xDF,0xFF,0xFF,0x02,0x00,0x03,0x00,0x0A,0xE2,0xFF,0xFF,0x03,0x00,0x04,0x00,0x58,0xE4,
	0xFF,0xFF,0x04,0x00,0x05,0x00,0xA6,0xE6,0xFF,0xFF,0x05,0x00,0x06,0x00,0xF4,0xE8,0xFF,0xFF,0x06,0x00,
	0x07,0x00,0x42,0xEB,0xFF,0xFF,0x07,0x00,0x08,0x00,0x90,0xED,0xFF,0xFF,0x08,0x00,0x09,0x00,0xDE,0xEF,
	0xFF,0xFF,0x09,0x00,0x0A,0x00,0x2C,0xF2,0xFF,0xFF,0x0A,0x00,0x0B,0x00,0x7A,0xF4,0xFF,0xFF,0x0B,0x00,
	0x0C,0x00,0xC8,0xF6,0xFF,0xFF,0x0C,0x00,0x0D,0x00,0x16,0xF9,0xFF,0xFF,0x0D,0x00,0x0E,0x00,0x64,0xFB,
	0xFF,0xFF,0x0E,0x00,0x0F,0x00,0xB2,0xFD,0xFF,0xFF,0x0F,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x10,0x00,
	0x11,0x00,0x4E,0x02,0x00,0x00,0x11,0x00,0x12,0x00,0x9C,0x04,0x00,0x00,0x12,0x00,0x13,0x00,0xEA,0x06,
	0x00,0x00,0x13,0x00,0x14,0x00,0x38,0x09,0x00,0x00,0x14,0x00,0x15,0x00,0x86,0x0B,0x00,0x00,0x15,0x00,
	0x16,0x00,0xD4,0x0D,0x00,0x00,0x16,0x00,0x17,0x00,0x22,0x10,0x00,0x00,0x17,0x00,0x18,0x00,0x70,0x12,
	0x00,0x00,0x18,0x00,0x19,0x00,0xBE,0x14,0x00,0x00,0x19,0x00,0x1A,0x00,0x0C,0x17,0x00,0x00,0x1A,0x00,
	0x1B,0x00,0x5A,0x19,0x00,0x00,0x1B,0x00,0x1C,0x00,0xA8,0x1B,0x00,0x00,0x1C,0x00,0x1D,0x00,0xF6,0x1D,
	0x00,0x00,0x1D,0x00,0x1E,0x00,0x44,0x20,0x00,0x00,0x1E,0x00,0x1F,0x00,0x92,0x22,0x00,0x00,0x02,0x00,
	0x00,0x00,0x95,0xDE,0xFF,0xFF,0x03,0x00,0x01,0x00,0xE3,0xE0,0xFF,0xFF,0x04,0x00,0x02,0x00,0x31,0xE3,
	0xFF,0xFF,0x05,0x00,0x03,0x00,0x7F,0xE5,0xFF,0xFF,0x06,0x00,0x04,0x00,0xCD,0xE7,0xFF,0xFF,0x07,0x00,
	0x05,0x00,0x1B,0xEA,0xFF,0xFF,0x08,0x00,0x06,0x00,0x69,0xEC,0xFF,0xFF,0x09,0x00,0x07,0x00,0xB7,0xEE,
	0xFF,0xFF,0x0A,0x00,0x08,0x00,0x05,0xF1,0xFF,0xFF,0x0B,0x00,0x09,0x00,0x53,0xF3,0xFF,0xFF,0x0C,0x00,
	0x0A,0x00,0xA1,0xF5,0xFF,0xFF,0x0D,0x00,0x0B,0x00,0xEF,0xF7,0xFF,0xFF,0x0E,0x00,0x0C,0x00,0x3D,0xFA,
	0xFF,0xFF,0x0F,0x00,0x0D,0x00,0x8B,0xFC,0xFF,0xFF,0x10,0x00,0x0E,0x00,0xD9,0xFE,0xFF,0xFF,0x11,0x00,
	0x0F,0x00,0x27,0x01,0x00,0x00,0x12,0x00,0x10,0x00,0x75,0x03,0x00,0x00,0x13,0x00,0x11,0x00,0xC3,0x05,
	0x00,0x00,0x14,0x00,0x12,0x00,0x11,0x08,0x00,0x00,0x15,0x00,0x13,0x00,0x5F,0x0A,0x00,0x00,0x16,0x00,
	0x14,0x00,0xAD,0x0C,0x00,0x00,0x17,0x00,0x15,0x00,0xFB,0x0E,0x00,0x00,0x18,0x00,0x16,0x00,0x49,0x11,
	0x00,0x00,0x19,0x00,0x17,0x00,0x97,0x13,0x00,0x00,0x1A,0x00,0x18,0x00,0xE5,0x15,0x00,0x00,0x1B,0x00,
	0x19,0x00,0x33,0x18,0x00,0x00,0x1C,0x00,0x1A,0x00,0x81,0x1A,0x00,0x00,0x1D,0x00,0x1B,0x00,0xCF,0x1C,
	0x00,0x00,0x1E,0x00,0x1C,0x00,0x1D,0x1F,0x00,0x00,0x1F,0x00,0x1D,0x00,0x6B,0x21,0x00,0x00,0x00,0x00,
	0x02,0x00,0x95,0xDE,0xFF,0xFF,0x01,0x00,0x03,0x00,0xE3,0xE0,0xFF,0xFF,0x02,0x00,0x04,0x00,0x31,0xE3,
	0xFF,0xFF,0x03,0x00,0x05,0x00,0x7F,0xE5,0xFF,0xFF,0x04,0x00,0x06,0x00,0xCD,0xE7,0xFF,0xFF,0x05,0x00,
	0x07,0x00,0x1B,0xEA,0xFF,0xFF,0x06,0x00,0x08,0x00,0x69,0xEC,0xFF,0xFF,0x07,0x00,0x09,0x00,0xB7,0xEE,
	0xFF,0xFF,0x08,0x00,0x0A,0x00,0x05,0xF1,0xFF,0xFF,0x09,0x00,0x0B,0x00,0x53,0xF3,0xFF,0xFF,0x0A,0x00,
	0x0C,0x00,0xA1,0xF5,0xFF,0xFF,0x0B,0x00,0x0D,0x00,0xEF,0xF7,0xFF,0xFF,0x0C,0x00,0x0E,0x00,0x3D,0xFA,
	0xFF,0xFF,0x0D,0x00,0x0F,0x00,0x8B,0xFC,0xFF,0xFF,0x0E,0x00,0x10,0x00,0xD9,0xFE,0xFF,0xFF,0x0F,0x00,
	0x11,0x00,0x27,0x01,0x00,0x00,0x10,0x00,0x12,0x00,0x75,0x03,0x00,0x00,0x11,0x00,0x13,0x00,0xC3,0x05,
	0x00,0x00,0x12,0x00,0x14,0x00,0x11,0x08,0x00,0x00,0x13,0x00,0x15,0x00,0x5F,0x0A,0x00,0x00,0x14,0x00,
	0x16,0x00,0xAD,0x0C,0x00,0x00,0x15,0x00,0x17,0x00,0xFB,0x0E,0x00,0x00,0x16,0x00,0x18,0x00,0x49,0x11,
	0x00,0x00,0x17,0x00,0x19,0x00,0x97,0x13,0x00,0x00,0x18,0x00,0x1A,0x00,0xE5,0x15,0x00,0x00,0x19,0x00,
	0x1B,0x00,0x33,0x18,0x00,0x00,0x1A,0x00,0x1C,0x00,0x81,0x1A,0x00,0x00,0x1B,0x00,0x1D,0x00,0xCF,0x1C,
	0x00,0x00,0x1C,0x00,0x1E,0x00,0x1D,0x1F,0x00,0x00,0x1D,0x00,0x1F,0x00,0x6B,0x21,0x00,0x00,0x00,0x00,
	0x5E,0x00,0x1E,0x00,0x1E,0x00,0x00,0x00,0x3F,0x00,0x20,0x00,0x01,0x00,0x40,0x00,0x21,0x00,0x02,0x00,
	0x41,0x00,0x22,0x00,0x03,0x00,0x42,0x00,0x23,0x00,0x04,0x00,0x43,0x00,0x24,0x00,0x05,0x00,0x44,0x00,
	0x25,0x00,0x06,0x00,0x45,0x00,0x26,0x00,0x07,0x00,0x46,0x00,0x27,0x00,0x08,0x00,0x47,0x00,0x28,0x00,
	0x09,0x00,0x48,0x00,0x29,0x00,0x0A,0x00,0x49,0x00,0x2A,0x00,0x0B,0x00,0x4A,0x00,0x2B,0x00,0x0C,0x00,
	0x4B,0x00,0x2C,0x00,0x0D,0x00,0x4C,0x00,0x2D,0x00,0x0E,0x00,0x4D,0x00,0x2E,0x00,0x0F,0x00,0x4E,0x00,
	0x2F,0x00,0x10,0x00,0x4F,0x00,0x30,0x00,0x11,0x00,0x50,0x00,0x31,0x00,0x12,0x00,0x51,0x00,0x32,0x00,
	0x13,0x00,0x52,0x00,0x33,0x00,0x14,0x00,0x53,0x00,0x34,0x00,0x15,0x00,0x54,0x00,0x35,0x00,0x16,0x00,
	0x55,0x00,0x36,0x00,0x17,0x00,0x56,0x00,0x37,0x00,0x18,0x00,0x57,0x00,0x38,0x00,0x19,0x00,0x58,0x00,
	0x39,0x00,0x1A,0x00,0x59,0x00,0x3A,0x00,0x1B,0x00,0x5A,0x00,0x3B,0x00,0x1C,0x00,0x5B,0x00,0x3C,0x00,
	0x1D,0x00,0x5C,0x00,0x3D,0x00,0x1E,0x00,0x5D,0x00,0x3E,0x00,0x1F,0x00,0x5E,0x00,0x5F,0x00,0x60,0x00,
	0x61,0x00,0x62,0x00,0x63,0x00,0x64,0x00,0x65,0x00,0x66,0x00,0x67,0x00,0x68,0x00,0x69,0x00,0x6A,0x00,
	0x6B,0x00,0x6C,0x00,0x6D,0x00,0x6E,0x00,0x6F,0x00,0x70,0x00,0x71,0x00,0x72,0x00,0x73,0x00,0x74,0x00,
	0x75,0x00,0x76,0x00,0x77,0x00,0x78,0x00,0x79,0x00,0x7A,0x00,0x7B,0x00,0x7C,0x00,0x7D,0x00,0x7E,0x00,
	0x7F,0x00,0x80,0x00,0x81,0x00,0x82,0x00,0x83,0x00,0x84,0x00,0x85,0x00,0x86,0x00,0x87,0x00,0x88,0x00,
	0x89,0x00,0x8A,0x00,0x8B,0x00,0x8C,0x00,0x8D,0x00,0x8E,0x00,0x8F,0x00,0x90,0x00,0x91,0x00,0x92,0x00,
	0x93,0x00,0x94,0x00,0x95,0x00,0x96,0x00,0x97,0x00,0x98,0x00,0x99,0x00,0x00,0x00 };

const unsigned short L32_usPosF1 = 32;
const unsigned short L32_usPosF2 = 32 + 31;
const unsigned short L32_usPosF3 = 32 + 62;
const unsigned short L32_usPosF4 = 32 + 62 + 30;

int LoadMap_L32(LIB_L32 *pLib)
{
	if (4 > L32_MAP_SIZE)
		return L32_ERR_UNKNOWN;
	unsigned short *pH = (unsigned short*)L32_aMap;
	if (pH[0] * 4 + 2 > L32_MAP_SIZE)
		return L32_ERR_UNKNOWN;
	unsigned short *pAxisC = (unsigned short*)(L32_aMap + pH[0] * 4);
	if (pH[0] * 4 + 2 + (*pAxisC) * sizeof(AXIS_EX_L32) > L32_MAP_SIZE)
		return L32_ERR_UNKNOWN;
	pLib->usAxisCount = *pAxisC;
	pLib->pAxisInfo = (AXIS_EX_L32*)(pAxisC + 1);
	if (pH[1] * 4 + 6 > L32_MAP_SIZE)
		return L32_ERR_UNKNOWN;
	unsigned short *pCnt = (unsigned short*)(L32_aMap + pH[1] * 4);
	int nCnt = pCnt[0] + pCnt[1] + pCnt[2];
	if (pH[1] * 4 + 6 + nCnt * 2 > L32_MAP_SIZE
		|| nCnt > pLib->usAxisCount)
		return L32_ERR_UNKNOWN;
	unsigned short *pCurId = pCnt + 3;
	LAYER_L32 *pCurLayer = pLib->aLayer;
	for (int i = 0; i < 3; ++i)
	{
		pCurLayer->ucState = 0;
		pCurLayer->ucPer = 100;
		pCurLayer->pAxisT = pCurId;
		pCurId += pCnt[i];
		pCurLayer->pAxisB = pCurId - 1;
		pCurLayer++;
	}
	return L32_RET_OK;
}

int CheckLib_L32(LIB_L32 *pLib)
{
	for (int i = 0; i < 3; ++i)
	{
		unsigned short *pCurId = pLib->aLayer[i].pAxisT;
		unsigned short *pAxisB = pLib->aLayer[i].pAxisB;
		while (pCurId <= pAxisB)
		{
			if ((*pCurId) >= pLib->usAxisCount)
				return L32_ERR_UNKNOWN;
			pCurId++;
		}
	}
	return L32_RET_OK;
}

int InitDev_L32(LIB_L32 *pLib, DEV_INFO *pDev)
{
	unsigned char *pMem;
	int nMemSize = FourByteAlign(pLib->usAxisCount * sizeof(AXIS_L32));
	MallocStaticMem(pMem, nMemSize, unsigned char,
		pLib, return L32_ERR_MEMOUT);
	AXIS_L32 *pCurAxisS = (AXIS_L32*)pMem;
	pLib->pAxisState = pCurAxisS;
	AXIS_L32 *pAxisSE = pCurAxisS
		+ pLib->usAxisCount;
	while (pCurAxisS < pAxisSE)
	{
		pCurAxisS->ucFlag = L32_AXIS_APPEAR;
		pCurAxisS->usData = 0;
		pCurAxisS++;
	}
	pDev->pCalcData = pLib;
	///////////Init FrameBuf
	int nHeaderSize = FourByteAlign(sizeof(HW_FRAME));
	int nBufSize = FourByteAlign(32 * 2);
	nMemSize = (nHeaderSize + nBufSize) * 2;
	MallocStaticMem(pMem, nMemSize, unsigned char,
		pLib, return L32_ERR_MEMOUT);
	HW_FRAME *pFrameBuf = (HW_FRAME*)pMem;
	pMem += nHeaderSize;
	pDev->pScanBuf = pFrameBuf;
	pFrameBuf->ucDevVer = DEV_VER_L32;
	pFrameBuf->ucScanFlag = 0;
	pFrameBuf->unScanTick = 0;
	pFrameBuf->usDataSize = 34;
	pFrameBuf->usBufSize = nBufSize;
	pFrameBuf->pBuf = pMem;
	pMem += nBufSize;
	pFrameBuf = (HW_FRAME*)pMem;
	pMem += nHeaderSize;
	pDev->pCalcBuf = pFrameBuf;
	pFrameBuf->ucDevVer = DEV_VER_L32;
	pFrameBuf->ucScanFlag = 0;
	pFrameBuf->unScanTick = 0;
	pFrameBuf->usDataSize = 34;
	pFrameBuf->usBufSize = nBufSize;
	pFrameBuf->pBuf = pMem;
	return L32_RET_OK;
}

void InitParam_L32(LIB_L32 *pLib)
{
	pLib->ucHoldFC = 0;
	pLib->ucHoldDely = 0;
	pLib->ucPowerCD = 0;
	pLib->usHorBrt[0] = 0;
	pLib->usHorBrt[1] = 0;
	pLib->usHorBrt[2] = 0;
	pLib->nIntY = 0;
}


int InitCalcSys_L32(DEV_INFO * pDev)
{
	int nSize = pDev->nCalcMemSize;
	if (nSize < sizeof(LIB_L32))
		return L32_ERR_MEMOUT;
	int nLibSize = FourByteAlign(sizeof(LIB_L32));
	unsigned char *pMem = pDev->pCalcMemBuf;
	LIB_L32 *pLib = (LIB_L32*)pMem;
	InitCalcMemSys(pMem + nLibSize,
		nSize - nLibSize, pLib);
	int nRet = LoadMap_L32(pLib);
	if (nRet == L32_RET_OK)
	{
		nRet = CheckLib_L32(pLib);
		if (nRet == L32_RET_OK)
		{
			nRet = InitDev_L32(pLib, pDev);
			if (nRet == L32_RET_OK)
				InitParam_L32(pLib);
		}
	}
	return nRet;
}

void SwapFrame_L32(DEV_INFO * pDev)
{
	HW_FRAME *pBuf = pDev->pScanBuf;
	pDev->pScanBuf = pDev->pCalcBuf;
	pDev->pCalcBuf = pBuf;
}

int CalcFrame_L32(DEV_INFO * pDev)
{
	HW_FRAME *pBuf = pDev->pCalcBuf;
	if (pBuf->usDataSize < 64)
		return L32_ERR_UNKNOWN;
	unsigned short *pSrc = (unsigned short*)pBuf->pBuf;
	unsigned short *pEOF = pSrc + 32;
	LIB_L32 *pLib = (LIB_L32*)(pDev->pCalcData);
	AXIS_L32 *pStateH = pLib->pAxisState;
	AXIS_L32 *pStateA = pStateH;
 	switch (pBuf->ucScanFlag)
	{
	case 1:
		pStateA += L32_usPosF1;
		pSrc++;
		break;
	case 2:
		pStateA += L32_usPosF2;
		pEOF--;
		break;
	case 3:
		pStateA += L32_usPosF3;
		pSrc += 2;
		break;
	case 4:
		pStateA += L32_usPosF4;
		pEOF -= 2;
		break;
	default:
		break;
	}
#define L32_BRT_CNT			8
	unsigned short aMaxData[L32_BRT_CNT] = { 0, };
	unsigned short *pData = pSrc;
	do
	{
		unsigned short usData = (*pData);
		for (int i = 0; i < L32_BRT_CNT; ++i)
		{
			if (usData > aMaxData[i])
			{
				for (int j = i + 1; j < L32_BRT_CNT; ++j)
					aMaxData[j] = aMaxData[j - 1];
				aMaxData[i] = usData;
				break;
			}
		}
		pData++;
	} while (pData < pEOF);
	int nBrt = aMaxData[0];
	int nCmp = nBrt / 4;
	int nMainCnt = 1;
	do
	{
		if (aMaxData[nMainCnt] <= nCmp)
			break;
		nBrt += aMaxData[nMainCnt];
		nMainCnt++;
	} while (nMainCnt < L32_BRT_CNT);
	nBrt /= nMainCnt;
	int nCmpH = nBrt / 3;
	int nBrtSum = nBrt;
	int nBrtCnt = 1;
	int nId = 0;
	AXIS_L32 *pStateE = pStateA;
	do
	{
		unsigned short usData = (*pSrc);
		pStateE->usData = usData;
		if (usData > nCmp)
		{
			nBrtSum += usData;
			nBrtCnt++;
		}
		pStateE++;
		pSrc++;
	} while (pSrc < pEOF);
	if (nBrtCnt > nMainCnt)
		nBrt = nBrtSum / nBrtCnt;
	if (pBuf->ucScanFlag <= 2
		&& nBrt > 200)
		pLib->usHorBrt[pBuf->ucScanFlag] = (unsigned short)nBrt;
	////////////////////////////////////////
	AXIS_L32 *pCurS = pStateA;
	do
	{
		unsigned short usData = pCurS->usData;
		if (usData < 35)
		{
			pCurS->ucFlag |= L32_AXIS_APPEAR;
			if ((pCurS->ucFlag & 0x0F) != 0x0F)
				pCurS->ucFlag++;
		}
		else
		{
			if (usData > nCmpH)
				nCmp = ((usData + nCmpH) >> 1);
			else
				nCmp = nCmpH;
			int nCntTmpL = 1;
			int nCntTmpR = 0;
			int nSumTmp = nBrt;
			AXIS_L32 *pState = pCurS - 1;
			for (int i = 0; i < 5; ++i)
			{
				if (pState < pStateA)
					break;
				if (pState->usData > nCmp)
				{
					nSumTmp += pState->usData;
					nCntTmpL++;
					if (nCntTmpL > 3)
						break;
				}
				pState--;
			}
			pState = pCurS + 1;
			for (int i = 0; i < 5; ++i)
			{
				if (pState >= pStateE)
					break;
				if (pState->usData > nCmp)
				{
					nSumTmp += pState->usData;
					nCntTmpR++;
					if (nCntTmpR > 3)
						break;
				}
				pState++;
			}
			nCntTmpL += nCntTmpR;
			nSumTmp /= nCntTmpL;

			if (nSumTmp < 950)
			{
				if (pCurS->ucFlag&L32_AXIS_APPEAR)
				{
					if (usData > 150
						|| (usData > 250 && nSumTmp >= 900))
					{
						if ((pCurS->ucFlag & 0x0F) > 1)
						{
							pCurS->ucFlag &= 0xF0;
							pCurS->ucFlag |= 0x01;
						}
						else
							pCurS->ucFlag &= ~(L32_AXIS_APPEAR | 0x0F);
					}
					else
					{
						if ((pCurS->ucFlag & 0x0F) != 0x0F)
							pCurS->ucFlag++;
					}
				}
				else
				{
					if (usData < 100
						|| (usData < 200 && nSumTmp >= 900))
					{
						if ((pCurS->ucFlag & 0x0F) >= 0)
							pCurS->ucFlag |= L32_AXIS_APPEAR;
						else
							pCurS->ucFlag++;
					}
					else
						pCurS->ucFlag &= 0xF0;
				}
			}
			else
			{
				if (usData < nSumTmp / 3)
				{
					pCurS->ucFlag |= L32_AXIS_APPEAR;
					if ((pCurS->ucFlag & 0x0F) != 0x0F)
						pCurS->ucFlag++;
				}
				else
					pCurS->ucFlag &= ~(L32_AXIS_APPEAR | 0x0F);
			}
		}
		pCurS++;
	} while (pCurS < pStateE);
	////////////////////////////////////////////
	nMainCnt = 0;
	AXIS_EX_L32 *pTagAxis = 0;
	unsigned char ucRetFlag = 0;
	if (pLib->usHorBrt[0] == 0
		|| pLib->usHorBrt[1] == 0
		|| pLib->usHorBrt[2] == 0)
		ucRetFlag |= 0x01;
	else
	{
		nCmp = 0;
		nCmpH = 0;
		LAYER_L32 *pLayerA = pLib->aLayer;
		AXIS_EX_L32 *pInfo = pLib->pAxisInfo;
		unsigned short *pAxisB = pLayerA->pAxisB;
		unsigned short *pCurId = pLayerA->pAxisT;
		while (pCurId <= pAxisB)
		{
			pCurS = pStateH + (*pCurId);
			if (pCurS->ucFlag&L32_AXIS_APPEAR)
			{
				nMainCnt++;
				nCmp++;
				if (nCmp == 2)
					pTagAxis = pInfo + (*pCurId);
				nCmpH += 1 + (pCurS->ucFlag & 0x0F);
				if (nCmp >= 2 || nCmpH >= 3)
				{
					if (nBrt >= 1100 || nCmp >= 3 || nCmpH >= 5)
					{
						pLib->nIntY = pInfo[*pCurId].nPhyY;
						ucRetFlag |= 0x01;
						break;
					}
				}
			}
			else
			{
				nCmp = 0;
				nCmpH = 0;
			}
			pCurId++;
		}

		int nAvgB[3];
		for (int i = 1; i < 3; ++i)
		{
			aMaxData[0] = 0xFFFF;
			LAYER_L32 *pLayer = pLayerA + i;
			unsigned short *pAxisB = pLayer->pAxisB;
			unsigned short *pAxisT = pLayer->pAxisT;
			do
			{
				unsigned short usData = pStateH[*pAxisT].usData;
				for (int i = 0; i < L32_BRT_CNT; ++i)
				{
					if (usData < aMaxData[i])
					{
						for (int j = i + 1; j < L32_BRT_CNT; ++j)
							aMaxData[j] = aMaxData[j - 1];
						aMaxData[i] = usData;
						break;
					}
				}
				pAxisT++;
			} while (pAxisT <= pAxisB);
			nBrtCnt = 1;
			nBrtSum = aMaxData[0];
			while (nBrtCnt < L32_BRT_CNT)
			{
				if (aMaxData[nBrtCnt] == 0xFFFF)
					break;
				nBrtSum += aMaxData[nBrtCnt];
				nBrtCnt++;
			}
			nAvgB[i] = nBrtSum / nBrtCnt;
		}

		nBrt = (pLib->usHorBrt[0] + pLib->usHorBrt[1] + pLib->usHorBrt[2]) / 3;
		if (nBrt >= 1000)
			nCmp = 85;
		else
		{
			nCmp = 20;
			if (nBrt > 300)
				nCmp += 65 * (nBrt - 300) / 700;
		}
		nCmpH = nCmp + 5;
		int nSecCnt = 0;
		AXIS_EX_L32 *pSecAxis = 0;
		for (int i = 1; i < 3; ++i)
		{
			LAYER_L32 *pLayer = pLayerA + i;
			if (i == 1)
				nBrtSum = nAvgB[1] + nAvgB[1] + nAvgB[2];
			else
				nBrtSum = nAvgB[2] + nAvgB[2] + nAvgB[1];
			nBrtSum /= 3;
			nBrtCnt = nBrtSum * 100 / nBrt;
			pLayer->ucPer = (unsigned char)nBrtCnt;
			if (pLayer->ucState == L32_LAYER_DISABLE)
			{
				if (nBrtCnt > nCmpH || nBrt < 1100)
				{
					pLayer->ucState = 0;
					pAxisB = pLayer->pAxisB;
					pCurId = pLayer->pAxisT;
					do
					{
						pStateH[*pCurId].ucFlag &= ~(L32_AXIS_IGNORE | 0x0F);
						pCurId++;
					} while (pCurId <= pAxisB);
					continue;
				}
			}
			else
			{
				if (nBrtCnt > nCmp || nBrt < 1500)
					continue;
				pLayer->ucState = L32_LAYER_DISABLE;
				pAxisB = pLayer->pAxisB;
				pCurId = pLayer->pAxisT;
				do
				{
					pStateH[*pCurId].ucFlag |= L32_AXIS_IGNORE;
					pCurId++;
				} while (pCurId <= pAxisB);
			}
		}

		if (ucRetFlag == 0)
		{
			for (int i = 1; i < 3; ++i)
			{
				LAYER_L32 *pCurLayer = pLayerA + i;
				if (pCurLayer->ucState != L32_LAYER_DISABLE)
				{
					pAxisB = pCurLayer->pAxisB;
					pCurId = pCurLayer->pAxisT;
					if (pCurId <= pAxisB)
					{
						unsigned short usIdT = 0xFFFF;
						unsigned short usIdB = 0xFFFF;
						do
						{
							if ((pStateH[*pCurId].ucFlag&L32_AXIS_APPEAR))
							{
								if (usIdT == 0xFFFF)
									usIdT = *pCurId;
								if (pCurId == pAxisB)
								{
									usIdB = *pCurId;
									goto CHECK_AXIS;
								}
							}
							else
							{
								if (usIdT != 0xFFFF)
								{
									usIdB = *(pCurId - 1);
								CHECK_AXIS:
									if (usIdT == usIdB)
									{
										nCmpH = 1 + (pStateH[usIdT].ucFlag & 0x0F);
										if (nCmpH >= 3)
										{
											if (nCmpH >= 5
												|| (nBrt >= 1200
													&& pCurLayer->ucPer > 95))
											{
												pLib->nIntY = pInfo[usIdT].nPhyY;
												ucRetFlag |= 0x01;
												break;
											}
											nCmpH = 2;
										}
										nCmp = 1;
										unsigned short usL = pInfo[usIdT].usLedL;
										unsigned short usR = pInfo[usIdT].usLedR;
										for (int j = i - 1; j >= 0; --j)
										{
											LAYER_L32 *pTmpLayer = pLayerA + j;
											if (pTmpLayer->ucState != L32_LAYER_DISABLE)
											{
												unsigned short *pTmpB = pTmpLayer->pAxisB;
												unsigned short *pTmpId = pTmpLayer->pAxisT;
												while (pTmpId <= pTmpB)
												{
													AXIS_EX_L32 *pCurA = pInfo + (*pTmpId);
													if (pCurA->usLedL >= usL
														|| pCurA->usLedR >= usR)
													{
														if (pCurA->usLedL > usL
															&&pCurA->usLedR > usR)
															break;
														if (pStateH[*pTmpId].ucFlag&L32_AXIS_APPEAR)
														{
															pTagAxis = pCurA;
															nCmp++;
															if (pStateH[*pTmpId].ucFlag & 0x0F)
																nCmpH += 2;
															else
																nCmpH++;
															if (nCmpH >= 5
																|| (((nCmp >= 3 || nCmpH >= 3)) && nBrt >= 1200
																	&& pCurLayer->ucPer + pTmpLayer->ucPer > 190))
															{
																pLib->nIntY = pInfo[usIdT].nPhyY;
																ucRetFlag |= 0x01;
																break;
															}
														}
													}
													pTmpId++;
												}
												if (ucRetFlag)
													break;
											}
										}
									}
									else if (nMainCnt > 0)
									{
										nCmpH = 0;
										unsigned short usLT = pInfo[usIdT].usLedL;
										unsigned short usRT = pInfo[usIdT].usLedR;
										unsigned short usLB = pInfo[usIdB].usLedL;
										unsigned short usRB = pInfo[usIdB].usLedR;
										unsigned short *pTmpB = pLayerA->pAxisB;
										unsigned short *pTmpId = pLayerA->pAxisT;
										while (pTmpId <= pTmpB)
										{
											AXIS_EX_L32 *pCurA = pInfo + (*pTmpId);
											if (pCurA->usLedL >= usLT
												|| pCurA->usLedR >= usRT)
											{
												if (pCurA->usLedL > usLB
													&&pCurA->usLedR > usRB)
													break;
												pCurS = pStateH + (*pTmpId);
												if (pCurS->ucFlag&L32_AXIS_APPEAR)
												{
													pTagAxis = pCurA;
													nCmpH += 1 + (pCurS->ucFlag & 0x0F);
													if (nBrt >= 1200 || nCmpH > 1)
													{
														pLib->nIntY = pCurA->nPhyY;
														ucRetFlag |= 0x01;
														break;
													}
												}
											}
											pTmpId++;
										}
									}
									if (ucRetFlag)
										break;
									usIdT = 0xFFFF;
								}
							}
							pCurId++;
						} while (pCurId <= pAxisB);
						if (ucRetFlag)
							break;
					}
				}
			}

			if (ucRetFlag == 0
				&& pLib->ucHoldDely > 0
				&& pLayerA[1].ucState == L32_LAYER_DISABLE
				&&pLayerA[2].ucState == L32_LAYER_DISABLE)
			{
				if (nSecCnt > 0)
				{
					if (nSecCnt + nMainCnt >= 3)
					{
						pLib->nIntY = pSecAxis->nPhyY;
						ucRetFlag |= 0x01;
					}
					else
						ucRetFlag |= 0x80;
				}
			}
		}
	}

	if (ucRetFlag & 0x0F)
	{
		pLib->ucHoldFC = L32_HOLD_FC;
		pLib->ucHoldDely = L32_HOLD_DELY;
		return L32_RET_COVER;
	}
	else
	{
		if (pTagAxis)
		{
			pLib->nIntY = pTagAxis->nPhyY;
			if (pLib->ucHoldFC >= L32_HOLD_FC)
			{
				pLib->ucHoldDely = L32_HOLD_DELY;
				return L32_RET_COVER;
			}
			pLib->ucHoldFC += 2;
			if (pLib->ucHoldDely)
			{
				if (pLib->ucHoldDely < L32_HOLD_DELY)
					pLib->ucHoldDely++;
				return L32_RET_COVER;
			}
		}
		else
		{
			if (pLib->ucHoldFC > 0)
				pLib->ucHoldFC--;
			if (pLib->ucHoldDely)
			{
				if (ucRetFlag <= 0x0F)
					pLib->ucHoldDely--;
				return L32_RET_COVER;
			}
		}
	}
	return L32_RET_OK;
}

int GetPower_L32(DEV_INFO * pDev)
{
	static int nDownCD = -1;
	LIB_L32 *pLib = (LIB_L32*)(pDev->pCalcData);
	if (pLib->ucPowerCD == 0)
	{
		if (pLib->usHorBrt[0] != 0
			&& pLib->usHorBrt[1] != 0
			&& pLib->usHorBrt[2] != 0)
		{
			unsigned short usBrt = (pLib->usHorBrt[0] 
				+ pLib->usHorBrt[1] + pLib->usHorBrt[2]) / 3;
			if (usBrt < 500)
			{
				pLib->ucPowerCD = 5;
				nDownCD = -1;
				return 1;
			}
			if (usBrt > 1680)
			{
				if (nDownCD == -1)
					nDownCD = 0;
			}
			if (nDownCD >= 0)
			{
				if (nDownCD == 5)
				{
					pLib->ucPowerCD = 5;
					nDownCD = -1;
					return -1;
				}
				nDownCD++;
			}
		}
	}
	else
		pLib->ucPowerCD--;
	return 0;
}

int GetErrLed_L32(DEV_INFO * pDev)
{
	return 0;
}
